#ifndef STATEMACHINE_H
#define STATEMACHINE_H

#include <cassert>
#include <string>
#include "State.h"

template <class EntityType>

class StateMachine
{
private:
	EntityType* pOwner;
	State<EntityType>* pCurrentState;
	State<EntityType>* pPreviousState;
	State<EntityType>* pGlobalState;

public:
	//QUESTION: Can we see about building this as a default constructor instead of a...whatever this is? - K13
	//ANSWER:
	StateMachine(EntityType* owner):  pOwner(owner),
		pCurrentState(NULL),
		pPreviousState(NULL),
		pGlobalState(NULL)
	{}

	virtual ~StateMachine() {} //Default Deconstructor

	//QUESTION: What the hell is 's' anyway? And what is it's function? - K13
	//ANSWER:
	void SetCurrentState(State<EntityType>* s) {pCurrentState = s; }
	void SetGlobalState(State<EntityType>* s) {pGlobalState = s; }
	void SetPreviousState(State<EntityType>* s) {pPreviousState = s; }


	void Update()const
	{
		//Call this to update the FSM
		if(pGlobalState)	pGlobalState->Execute(pOwner);
		if(pCurrentState)	pCurrentState->Execute(pOwner);

	}


	void ChangeState(State<EntityType>* pNewState)
	{
		assert(pNewState && "<StateMachine::ChangeState>: trying to change to NULL state");

		pPreviousState = pCurrentState; 	//1) Record current state as previous state
		pCurrentState->Exit(pOwner); 		//2) Call exit of current state
		pCurrentState = pNewState;			//3) Change to new state
		pCurrentState->Enter(pOwner); 		//4) Enter new state
	}


	void RevertToPreviousState()			
	{
		//Calls Previous State
		ChangeState(pPreviousState);
	}



	bool isInState(const State<EntityType>& st)const
	{
		//Takes a class as a parameter and returns true if already in that state
		//We can use this to stop the AI from entering a state twice.
		
		if (typeid(*pCurrentState) == typeid(st)) 
		{
			return true;
		}
		return false;
	}

	
	//Here's some get functions 
	//Datatype			Function Name		Purpose
	State<EntityType>*  GetCurrentState()	const{return pCurrentState;}
	State<EntityType>*  GetGlobalState()	const{return pGlobalState;}
	State<EntityType>*  GetPreviousState()	const{return pPreviousState;}

};